
/**
 * @file singletonguard.cpp
 * @brief 单例保护机制实现文件
 * @note  包含工厂模式实现和平台适配逻辑
 */
#include "singletonguard.h"



#ifdef Q_OS_WIN // Windows 专有代码需要条件编译

/**
 * @brief 创建命名互斥体并检测实例状态
 * @param appName 应用程序唯一标识符
 * @note  错误处理逻辑：
 *        1. 创建成功且无已存在实例 -> 单例状态
 *        2. 创建成功但存在实例 -> 关闭句柄并标记非单例
 *        3. 创建失败 -> 默认标记非单例
 */
MutexSingletonGuard::MutexSingletonGuard(const QString &appName) {
    hMutex = CreateMutexW(nullptr, TRUE, appName.toStdWString().c_str());
    DWORD lastError = GetLastError();
    if (hMutex && lastError != ERROR_ALREADY_EXISTS) {
        m_isSingle = true;  // 成功创建且无冲突
    } else {
        if (hMutex) CloseHandle(hMutex); // 清理残留句柄
        m_isSingle = false; // 存在冲突实例
    }
}
#endif

MutexSingletonGuard::~MutexSingletonGuard() { if (hMutex) CloseHandle(hMutex); }

bool MutexSingletonGuard::isSingleInstance() { return m_isSingle; }



/**
 * @brief 通过共享内存存在性判断实例状态
 * @param appName 共享内存唯一标识
 * @note 检测流程：
 *       1. 尝试附加到现有共享内存 -> 存在其他实例
 *       2. 创建新共享内存成功 -> 当前为首个实例
 */
SharedMemorySingletonGuard::SharedMemorySingletonGuard(const QString &appName) : sharedMemory(appName) {
    if (sharedMemory.attach()) {
        sharedMemory.detach(); // 解除当前进程关联
        m_isSingle = false; // 已存在运行实例
    } else {
        m_isSingle = sharedMemory.create(1);
    }
}

SharedMemorySingletonGuard::~SharedMemorySingletonGuard() { if (m_isSingle) sharedMemory.detach(); }

bool SharedMemorySingletonGuard::isSingleInstance() { return m_isSingle; }



/**
 * @brief 创建具体单例保护对象
 * @param type 枚举类型，指定实现方式
 * @param appName 程序唯一标识符
 * @return 单例保护对象指针
 * @note 平台适配逻辑：
 *       - Windows 优先使用系统互斥体
 *       - 其他平台使用共享内存方案
 */
std::unique_ptr<SingletonGuard> SingletonGuardFactory::create(SingletonType type, const QString &appName) {
    switch (type) {

#ifdef Q_OS_WIN// Windows 专有代码需要条件编译
    case SingletonType::SystemMutex:
        return std::unique_ptr<SingletonGuard>(new MutexSingletonGuard(appName));
#endif
    case SingletonType::SharedMemory:
        return std::unique_ptr<SingletonGuard>(new SharedMemorySingletonGuard(appName));
    default:
        return nullptr;
    }
}


/**
 * @brief 应用程序单例检测入口
 * @param appName 全局唯一应用标识
 * @return 是否允许继续运行
 * @note 平台适配策略：
 *       - Windows: 系统级互斥体
 *       - 其他平台: Qt共享内存方案
 */
bool checkOnly(const QString &appName)
{
    // 根据平台选择策略
    SingletonType singletonType =
        #ifdef Q_OS_WIN
            SingletonType::SystemMutex;
        #else
            SingletonType::SharedMemory; // 或 FileLock/NetworkPort
        #endif


    // 选择检测方式（通过枚举类型）
    auto guard = SingletonGuardFactory::create(singletonType, appName);

    if (!guard || !guard->isSingleInstance()) {
        QMessageBox::warning(nullptr, "Error", "程序已运行");
        return false;
    }

    return true;
}
